#!/usr/bin/env bash

# A rofi mode script that allows to open bookmarks from Firefox/Chromium
# or based browsers.
# by Adnan Shameem. License: MIT (Expat)
#
# Usage:
# - Download this into a dir
# - Make sure it's executable: chmod +x rofi-bookmarks.sh
# - For Firefox bookmark extraction to work, install sqlite
# - Run: rofi -modi "bookmarks:./rofi-bookmarks.sh" -show bookmarks
#   or, use this to include both run and bookmarks options:
#     rofi -combi-modi run,"bookmarks:./rofi-bookmarks.sh" -show combi

# Handle input
if [ ! -z "$@" ]; then
	coproc ( {{@@ webbrowser_exec @@}} "$@" )
    exit 0
fi

# Change prompt
echo -en "\0prompt\x1fbookmark\n"

# Extracts and prints bookmarks from a Firefox or based browser (such as
# IceCat, ABrowser, LibreWolf etc.)
# Params:
#   - $1: Profile dir, e.g. "~/.librewolf/k2fdb24c.default"
function extract_firefox_bookmarks() {

	places_found=$(find "${1}/" -type f -name "places.sqlite")
	if [ ! -z "$places_found" ] && [ ! -z "$(command -v sqlite3)" ]; then
		echo "$places_found" | while read -r place_file; do
			# Urlify file path (for file: protocol)
			places_db=$(echo "$place_file" | sed 's|?|%3f|' | sed 's|#|%23|' | sed 's|\/\/|\/|')

			sql_query="SELECT b.title, h.url FROM moz_places h JOIN moz_bookmarks b ON h.id = b.fk WHERE b.type = 1 AND b.title IS NOT NULL"

			sqlite3 -separator '^' "file:${places_db}?immutable=1" "$sql_query" | while IFS=^ read title url; do
				echo "${title} (${url})"
			done
		done
	fi

}

# List of profile directories to check
firefox_profiles=(
	"${HOME}/.mozilla/icecat/"
	"${HOME}/.mozilla/firefox/"
	"${HOME}/.mozilla/abrowser/"
	"${HOME}/.librewolf/"
	)

# Loop through profile dirs and list bookmarks from them
for profile in "${firefox_profiles[@]}"
do
	if [ -d "$profile" ]; then
		extract_firefox_bookmarks "$profile"
	fi
done

# Prints bookmarks when provided a Chromium/based browser profile directory.
# Params:
#   $1: Profile dir, where "Bookmarks" file lives
function extract_chromium_bookmarks() {

	bookmarks_found=$(find "${1}/" -type f -name "Bookmarks")
	if [ ! -z "$bookmarks_found" ]; then
		echo "$bookmarks_found" | while read -r bookmark_file; do
			# This brings in name (title), type and url - separated by a line of "--"
			grep -EB2 '"url":' "$bookmark_file" | \
			# We don't need the type line
			sed '/"type":/d' | \
			# We don't need the '--' line either
			sed '/^--$/d' | \
			# Join lines into one single line, so that it can be processed by grep
			sed -e ':a' -e 'N' -e '$!ba' -e 's/\n//g' | \
			# Find the title and url and show them on output
			sed -n -e 's|\s*"name": "\([^"]*\)"[^"]*"url": "\([^"]*\)"|\1 \(\2\)\n|pg'
		done
	fi

}

# List of profile directories to check
chromium_profiles=(
	"${HOME}/.config/iridium/Default/"
	"${HOME}/.config/BraveSoftware/Brave-Browser/Default/"
	"${HOME}/.config/chromium/Default/"
	)

# Loop through profile dirs and list bookmarks from them
for profile in "${chromium_profiles[@]}"
do
	if [ -d "$profile" ]; then
		extract_chromium_bookmarks "$profile"
	fi
done
